package com.xiaoshuidi.cloud.module.member.service.coupon;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.mybatis.core.util.MyBatisUtils;
import com.xiaoshuidi.cloud.framework.redis.lock.DistributeLock;
import com.xiaoshuidi.cloud.framework.security.core.util.SecurityFrameworkUtils;
import com.xiaoshuidi.cloud.framework.web.core.util.WebFrameworkUtils;
import com.xiaoshuidi.cloud.module.bpm.api.task.BpmProcessInstanceApi;
import com.xiaoshuidi.cloud.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import com.xiaoshuidi.cloud.module.bpm.enums.BpmBusinessTypeEnum;
import com.xiaoshuidi.cloud.module.member.controller.admin.coupon.vo.*;
import com.xiaoshuidi.cloud.module.member.controller.app.coupon.vo.CouponCustomerValidQueryVo;
import com.xiaoshuidi.cloud.module.member.convert.coupon.CouponConvert;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponSendMethodEnum;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponStatusEnum;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponTypeEnum;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponUseOverlayEnum;
import com.xiaoshuidi.cloud.module.member.mapper.coupon.CouponMapper;
import com.xiaoshuidi.cloud.module.member.pojo.coupon.CouponEntity;
import com.xiaoshuidi.cloud.module.member.pojo.coupon.CouponRecordEntity;
import com.xiaoshuidi.cloud.module.member.pojo.coupon.MemberCouponApartment;
import com.xiaoshuidi.cloud.module.member.pojo.user.MemberUser;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponApartmentRepository;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponCustomerRepository;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponRecordRespository;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponRepository;
import com.xiaoshuidi.cloud.module.member.service.user.MemberUserService;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.ApartmentApi;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.dto.ApartmentListDto;
import com.xiaoshuidi.cloud.module.system.api.user.AdminUserApi;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.member.enums.ErrorCodeConstants.*;

/**
 * @author Alex
 * @version generator
 * @description 优惠券表service层
 * @date 2023-03-14 15:06:11
 */
@Service
public class CouponService {
    public static final String DEDUCE_COUPONS_LOCK = "coupons:deduce:lock";//扣减优惠券的锁
    Logger logger = LoggerFactory.getLogger(CouponService.class);
    @Resource
    CouponMapper couponMapper;
    @Resource
    ApartmentApi apartmentApi;
    @Resource
    CouponCustomerService couponCustomerService;
    @Resource
    AdminUserApi adminUserApi;
    @Resource
    BpmProcessInstanceApi bpmProcessInstanceApi;
    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${bpm.processDefinitionKey}")
    private String processDefinitionKey;

    @Resource
    private MemberCouponRepository memberCouponRepository;

    @Resource
    private MemberCouponRecordRespository memberCouponRecordRespository;

    @Resource
    private MemberCouponCustomerRepository memberCouponCustomerRepository;

    @Resource
    private MemberCouponApartmentRepository memberCouponApartmentRepository;

    @Resource
    private MemberUserService userService;

    @Transactional(rollbackFor = Exception.class)
    public Long saveCoupon(CouponForm form) {
        //查看优惠券名称是否已存在
        CouponEntity coupon = memberCouponRepository.selectByCouponName(form.getCouponName());
        if (coupon != null) {
            throw exception(COUPON_NAME_EXIST);
        }
        CouponEntity entity = CouponConvert.INSTANCE.convert(form);
        entity.setFileUrls(JSONObject.toJSONString(form.getCouponUrl()));
        entity.setCouponUseOverlay(JSONObject.toJSONString(form.getCouponUseOverlays()));
        entity.setCreatedName(adminUserApi.getUser(WebFrameworkUtils.getLoginUserId()).getData().getNickname());
        if (entity.getCouponType().intValue() == CouponTypeEnum.RESERVATION_DISCOUNT.getNum().intValue()
                || entity.getCouponType().intValue() == CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum().intValue()
                || entity.getCouponType().intValue() == CouponTypeEnum.NEW_SIGNING_DISCOUNT.getNum().intValue()) {
            entity.setIssuingMethod(CouponSendMethodEnum.AUTOMATIC.getCode());
        } else {
            entity.setIssuingMethod(CouponSendMethodEnum.MANUAL.getCode());
        }
        entity.setSurplusStock(entity.getStock());
        entity.setCouponStatus(CouponStatusEnum.NOT_SUBMITTED.getValue());
        couponMapper.insert(entity);
        //加入门店关联表
        memberCouponApartmentRepository.insertApartment(entity.getId(), form.getApartmentIds());
        return entity.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateCoupon(CouponUpdateForm form) {
        CouponEntity coupon = couponMapper.selectById(form.getId());
        //如果修改了优惠券名称
        if (!coupon.getCouponName().equals(form.getCouponName())) {
            CouponEntity c = memberCouponRepository.selectByCouponName(form.getCouponName());
            if (c != null) {
                throw exception(COUPON_NAME_EXIST);
            }
        }
        //如果审批已通过，不可再修改
        if (CouponStatusEnum.NOT_SUBMITTED.getValue().equals(coupon.getCouponStatus()) || CouponStatusEnum.APPROVAL_REJECTION.getValue().equals(coupon.getCouponStatus())) {
            if (form.getCouponType() != null) coupon.setCouponType(form.getCouponType());
            if (form.getCouponName() != null) coupon.setCouponName(form.getCouponName());
            if (form.getPreferentialContentType() != null)
                coupon.setPreferentialContentType(form.getPreferentialContentType());
            if (form.getMarginPreference() != null) coupon.setMarginPreference(form.getMarginPreference());
            if (form.getPreferentialContentTypeOld() != null)
                coupon.setPreferentialContentTypeOld(form.getPreferentialContentTypeOld());
            if (form.getMarginPreferenceOld() != null) coupon.setMarginPreferenceOld(form.getMarginPreferenceOld());
            if (form.getStock() != null) coupon.setStock(form.getStock());
            if (form.getSurplusStock() != null) coupon.setSurplusStock(form.getSurplusStock());
            if (form.getUseRules() != null) coupon.setUseRules(form.getUseRules());
            if (form.getActivityStartTime() != null) coupon.setActivityStartTime(form.getActivityStartTime());
            if (form.getActivityEndTime() != null) coupon.setActivityEndTime(form.getActivityEndTime());
            if (form.getScheduledStartTime() != null) coupon.setScheduledStartTime(form.getScheduledStartTime());
            if (form.getScheduledEndTime() != null) coupon.setScheduledEndTime(form.getScheduledEndTime());
            if (form.getScheduledAmount() != null) coupon.setScheduledAmount(form.getScheduledAmount());
            if (form.getMiniLeaseMonth() != null) coupon.setMiniLeaseMonth(form.getMiniLeaseMonth());
            if (form.getMaxLeaseMonth() != null) coupon.setMaxLeaseMonth(form.getMaxLeaseMonth());
            if (form.getSigningStartTime() != null) coupon.setSigningStartTime(form.getSigningStartTime());
            if (form.getSigningEndTime() != null) coupon.setSigningEndTime(form.getSigningEndTime());
            if (form.getCouponUsageTimeType() != null) coupon.setCouponUsageTimeType(form.getCouponUsageTimeType());
            if (form.getCouponUsageTime() != null) coupon.setCouponUsageTime(form.getCouponUsageTime());
            if (form.getExpirationStartTime() != null) coupon.setExpirationStartTime(form.getExpirationStartTime());
            if (form.getExpirationEndTime() != null) coupon.setExpirationEndTime(form.getExpirationEndTime());
            if (form.getQuantityLimit() != null) coupon.setQuantityLimit(form.getQuantityLimit());
            if (form.getCouponStatus() != null) coupon.setCouponStatus(CouponStatusEnum.BEING_APPROVED.getValue());
            coupon.setCouponStatus(CouponStatusEnum.NOT_SUBMITTED.getValue());
            if (form.getCouponUseOverlays() != null && form.getCouponUseOverlays().size() > 0) {
                coupon.setCouponUseOverlay(JSONObject.toJSONString(form.getCouponUseOverlays()));
            }
            if (form.getCouponUrl() != null && form.getCouponUrl().size() > 0) {
                coupon.setFileUrls(JSONObject.toJSONString(form.getCouponUrl()));
            }
            couponMapper.updateById(coupon);
            //如果修改了门店
            if (form.getApartmentIds() != null && form.getApartmentIds().size() > 0) {
                memberCouponApartmentRepository.updateApartment(form.getId(), form.getApartmentIds());
            }

        } else {
            throw exception(COUPON_NOT_EDIT);
        }

    }

    public CouponDetailsVo queryCouponDetailed(Long couponId) {
        CouponEntity entity = couponMapper.selectById(couponId);
        if (entity != null) {
            CouponDetailsVo couponDetailsVo = new CouponDetailsVo();
            CouponDetailedOneVo vo = new CouponDetailedOneVo();
            logger.info("{}", JSONObject.toJSONString(entity));
            BeanUtils.copyProperties(entity, vo);
            logger.info("{}", JSONObject.toJSONString(vo));
            //获取门店信息
            List<MemberCouponApartment> apartments = memberCouponApartmentRepository.getApartmentsByCouponId(couponId);
            List<Long> appartmentIds = apartments.stream().map(MemberCouponApartment::getApartmentId).collect(Collectors.toList());
            vo.setApartmentIds(appartmentIds);
            StringBuffer sb = new StringBuffer();
            if (appartmentIds != null && appartmentIds.size() > 0) {
                for (int i = 0; i < appartmentIds.size(); i++) {
                    Long apartmentId = appartmentIds.get(i);
                    String name = "";
                    if (apartmentId.intValue() != -1) {
                        try {
                            CommonResult<ApartmentListDto> result = apartmentApi.getById(apartmentId);
                            if (result.isSuccess()) {
                                if (ObjectUtils.isNotEmpty(result.getData()) && StringUtils.isNotEmpty(result.getData().getName())) {
                                    name = result.getData().getName();
                                }
                            }
                        } catch (Exception e) {
                            logger.error("获取门店失败", e);
                        }
                    } else {
                        name = "不限门店";
                    }
                    if (i < (appartmentIds.size() - 1)) {
                        sb.append(name).append(",");
                    } else {
                        sb.append(name);
                    }
                }
            }

            vo.setActivityStoreName(sb.toString());
            vo.setProcessInstanceId(entity.getProcessInstanceId());
            couponDetailsVo.setCouponVo(vo);
            return couponDetailsVo;
        } else {
            throw exception(COUPON_NOT_EXIST);
        }
    }

    public PageResult<CouponListVo> queryCoupon(CouponQueryForm form) {
        IPage<CouponListVo> page = MyBatisUtils.buildPage(form);
        List<CouponListVo> list = couponMapper.selectCouponPage(page, form);
        for (CouponListVo vo : list) {
            StringBuffer sb = new StringBuffer();
            String[] apartmentIds = vo.getApartments().split(",");
            if (apartmentIds != null && apartmentIds.length > 0) {
                for (int i = 0; i < apartmentIds.length; i++) {
                    Long apartmentId = Long.valueOf(apartmentIds[i]);
                    String name = "";
                    if (apartmentId.intValue() != -1) {
                        try {
                            CommonResult<ApartmentListDto> result = apartmentApi.getById(apartmentId);
                            if (result.isSuccess()) {
                                if (ObjectUtils.isNotEmpty(result.getData()) && StringUtils.isNotEmpty(result.getData().getName())) {
                                    name = result.getData().getName();
                                }
                            }
                        } catch (Exception e) {
                            logger.error("获取门店失败", e);
                        }
                    } else {
                        name = "不限门店";
                    }
                    if (i < (apartmentIds.length - 1)) {
                        sb.append(name).append(",");
                    } else {
                        sb.append(name);
                    }
                }
            }
            vo.setActivityStoreName(sb.toString());
        }
        PageResult<CouponListVo> pageResult = new PageResult<>(list, page.getTotal());
        pageResult.setList(list);
        return pageResult;
    }

//	private Map<Long, WorkApprovedsEntity> getWorkApprovedsService(List<Long> couponIds) {
//
//		LambdaQueryWrapper<WorkApprovedsEntity> queryWrapper=new LambdaQueryWrapper();
//		queryWrapper.eq(WorkApprovedsEntity::getIsDelete,Boolean.FALSE)
//			.eq(WorkApprovedsEntity::getWorkType, WorkTypeEnum.Coupon_APPROVAL.getCode())
//			.in(CollectionUtils.isNotEmpty(couponIds),WorkApprovedsEntity::getRelatedObjId,couponIds)
//		;
//		List<WorkApprovedsEntity> workApprovedsEntityList = workApprovedsMapper.selectList(queryWrapper);
//		Map<Long, WorkApprovedsEntity> collect = workApprovedsEntityList.stream()
//			.collect(Collectors.toMap(WorkApprovedsEntity::getRelatedObjId, v -> v));
//		return collect;
//	}

	/*public PageData<CouponListVo> queryCouponApproved(CouponQueryDto dto){
		workApprovedsMapper.queryCouponApproved(dto);
		return null;
	}*/

    public CouponPageVo couponSummaryData() {
        CouponPageVo couponPageVo = new CouponPageVo();
        List<CouponSumVo> couponSumVos = new ArrayList<>();
        for (CouponSumVo couponSumVo : couponSumVos) {
            String couponStatus = couponSumVo.getStatus();
            //审批状态(0, u'待审批'),(1, u'已通过'),(2, u'已驳回'),
            if (couponStatus.equals("0")) {
                couponPageVo.setPendingapproval(couponSumVo.getSum());
            } else if (couponStatus.equals("2")) {
                couponPageVo.setRejected(couponSumVo.getSum());
            } else if (couponStatus.equals("1")) {
                couponPageVo.setPassed(couponPageVo.getPassed() + couponSumVo.getSum());
            }
        }
        return couponPageVo;
    }

    //根据id查询优惠券
    public CouponEntity queryCouponById(Long id) {
        return couponMapper.selectById(id);
    }

    //根据id查询优惠券
    public List<CouponEntity> queryCouponbyCondition(CouponCustomerPyVo couponCustomerPyVo) {
        LambdaQueryWrapper<CouponEntity> qw = new LambdaQueryWrapper();
        qw.eq(CouponEntity::getDeleted, Boolean.FALSE)
                .ge(CouponEntity::getActivityStartTime, new Date())
                .lt(CouponEntity::getActivityEndTime, new Date())
                .eq(couponCustomerPyVo.getActivityStore() != null, CouponEntity::getActivityStore, couponCustomerPyVo.getActivityStore())
                .ge(CouponEntity::getSigningStartTime, new Date())
                .lt(CouponEntity::getSigningEndTime, new Date())
                .eq(CouponEntity::getCouponType, couponCustomerPyVo.getCouponType())
        ;
        CouponTypeEnum couponType = CouponTypeEnum.getEnum(couponCustomerPyVo.getCouponType());
        switch (couponType) {
            case RESERVATION_DISCOUNT:
                qw.eq(CouponEntity::getScheduledAmount, couponCustomerPyVo.getScheduledAmount())
                        .ge(CouponEntity::getScheduledStartTime, couponCustomerPyVo.getScheduledTime())
                        .lt(CouponEntity::getScheduledEndTime, couponCustomerPyVo.getScheduledTime());
                break;
            case OLD_WITH_NEW_DISCOUNT:
                qw.ge(CouponEntity::getMiniLeaseMonth, couponCustomerPyVo.getLeaseMonth())
                        .lt(CouponEntity::getMaxLeaseMonth, couponCustomerPyVo.getLeaseMonth());
                break;
            case NEW_SIGNING_DISCOUNT:
                qw.ge(CouponEntity::getMiniLeaseMonth, couponCustomerPyVo.getLeaseMonth())
                        .lt(CouponEntity::getMaxLeaseMonth, couponCustomerPyVo.getLeaseMonth());
                break;
            default:
                break;
        }
        List<CouponEntity> source = couponMapper.selectList(qw);
        return source;
    }

    // 查询有效的优惠券
    public List<CouponCustomerValidQueryVo> queryValidCoupon(List couponStatusList) {
        LambdaQueryWrapper<CouponEntity> qw = new LambdaQueryWrapper();
        qw.eq(CouponEntity::getDeleted, Boolean.FALSE).in(CouponEntity::getCouponStatus, couponStatusList);
        List<CouponEntity> couponEntities = couponMapper.selectList(qw);
        List<CouponCustomerValidQueryVo> couponDtos = CouponConvert.INSTANCE.convert(couponEntities);
        return couponDtos;
    }

    //根据优惠券判断是否可用
    public Boolean checkCouponAvailable(List<Long> ids) {
        LambdaQueryWrapper<CouponEntity> qw = new LambdaQueryWrapper();
        qw.eq(CouponEntity::getDeleted, Boolean.FALSE)
                .eq(CouponEntity::getCouponStatus, CouponStatusEnum.IN_PROGRESS.getCode())
                .in(CouponEntity::getId, ids)
        ;
        List<CouponEntity> couponEntities = couponMapper.selectList(qw);
        if (CollectionUtils.isNotEmpty(couponEntities)) {
            List<CouponEntity> couponEntity = couponEntities.stream().filter(item ->
                    item.getCouponUseOverlay().isEmpty()).collect(Collectors.toList());
            //是空  判断同一类型使用  |不同类型使用
            if (CollectionUtils.isEmpty(couponEntity)) {
                return isFlag(couponEntities);
            }
            //不是空看是否  还有其他优惠券
            if (couponEntities.size() > 1) {
                return false;
            } else {
                return true;
            }
        }
        return false;
    }

    //判断是否可以叠加优惠券
    private static boolean isFlag(List<CouponEntity> list) {
        for (int i = 0; i < list.size(); i++) {
            CouponEntity couponEntity = list.get(i);
            for (int j = i + 1; j < list.size(); j++) {
                CouponEntity coupon = list.get(j);
                String code;
                if (couponEntity.getCouponType().equals(coupon.getCouponType())) {
                    code = CouponUseOverlayEnum.SAME_TYPE_COUPON.getCode();
                } else {
                    code = CouponUseOverlayEnum.OTHER_TYPE_COUPON.getCode();
                }
                if (!couponEntity.getCouponUseOverlay().contains(code)
                        || !coupon.getCouponUseOverlay().contains(code)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 优惠明细
     *
     * @param form 查询参数
     */
    public PageResult<CouponDetailedVo> detailed(CouponDetailedForm form) {
        IPage<CouponDetailedVo> page = MyBatisUtils.buildPage(form);
        List<CouponDetailedVo> list = couponMapper.couponDetailed(page, form);
        PageResult<CouponDetailedVo> pageResult = new PageResult<>(list, page.getTotal());
        pageResult.setList(list);
        return pageResult;
    }

    /**
     * 删除优惠活动
     *
     * @param couponId 优惠id
     */
    public void delete(Long couponId) {
        CouponEntity entity = couponMapper.selectById(couponId);
        if (entity != null) {
            couponMapper.deleteById(couponId);
        }
    }

    /**
     * 启动优惠活动
     *
     * @param couponId 优惠id
     */
    public void start(Long couponId) {
        CouponEntity coupon = couponMapper.selectById(couponId);
        if (coupon == null || Boolean.TRUE.equals(coupon.getDeleted())) {
            throw exception(COUPON_NOT_EXIST);
        }
        if (!CouponStatusEnum.NOT_STARTED.getCode().equals(coupon.getCouponStatus())) {
            throw exception(COUPON_STATUS_UNAVAILABLE);
        }
        if (coupon.getActivityEndTime().getTime() < System.currentTimeMillis()) {
            throw exception(COUPON_EXPIRE);
        }
        coupon.setCouponStatus(coupon.getActivityStartTime().getTime() < System.currentTimeMillis() ?
                CouponStatusEnum.IN_PROGRESS.getCode() : CouponStatusEnum.NOT_STARTED.getCode());
        couponMapper.updateById(coupon);
    }

    /**
     * 停止优惠活动
     *
     * @param couponId 优惠id
     */
    public void stop(Long couponId) {
        CouponEntity coupon = couponMapper.selectById(couponId);
        if (!CouponStatusEnum.IN_PROGRESS.getCode().equals(coupon.getCouponStatus())) {
            throw exception(COUPON_STATUS_UNAVAILABLE);
        }
        coupon.setCouponStatus(CouponStatusEnum.TERMINATED.getCode());
        couponMapper.updateById(coupon);
    }

    /**
     * 优惠活动下拉选择
     */
    public List<CouponSelectVo> couponSelect() {
        return couponMapper.couponSelect();
    }

    //根据时间查询
    public List<CouponEntity> queryCouponByTime() {
        LambdaQueryWrapper<CouponEntity> qw = new LambdaQueryWrapper<>();
        qw.eq(CouponEntity::getDeleted, Boolean.FALSE)
                .eq(CouponEntity::getCouponStatus, CouponStatusEnum.NOT_STARTED.getCode())
                .ge(CouponEntity::getActivityStartTime, new Date())
        ;
        return couponMapper.selectList(qw);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean toApproval(Long id) {
        CouponEntity entity = couponMapper.selectById(id);
        if (entity == null) {
            throw exception(COUPON_NOT_EXIST);
        }
        String instanceId = createProcessInstance(entity);
        entity.setCouponStatus(CouponStatusEnum.BEING_APPROVED.getValue());
        entity.setProcessInstanceId(instanceId);
        couponMapper.updateById(entity);
        return true;
    }

    public PageResult<CouponListVo> queryApproveCoupon(CouponQueryForm form) {
        IPage<CouponListVo> page = MyBatisUtils.buildPage(form);
        List<CouponListVo> list = couponMapper.selectCouponPage(page, form);
        for (CouponListVo vo : list) {
            StringBuffer sb = new StringBuffer();
            String[] apartmentIds = vo.getApartments().split(",");
            if (apartmentIds != null && apartmentIds.length > 0) {
                for (int i = 0; i < apartmentIds.length; i++) {
                    Long apartmentId = Long.valueOf(apartmentIds[i]);
                    String name = "";
                    if (apartmentId.intValue() != -1) {
                        try {
                            CommonResult<ApartmentListDto> result = apartmentApi.getById(apartmentId);
                            if (result.isSuccess()) {
                                if (ObjectUtils.isNotEmpty(result.getData()) && StringUtils.isNotEmpty(result.getData().getName())) {
                                    name = result.getData().getName();
                                }
                            }
                        } catch (Exception e) {
                            logger.error("获取门店失败", e);
                        }
                    } else {
                        name = "不限门店";
                    }
                    if (i < (apartmentIds.length - 1)) {
                        sb.append(name).append(",");
                    } else {
                        sb.append(name);
                    }
                }
            }
            vo.setActivityStoreName(sb.toString());
        }
        PageResult<CouponListVo> pageResult = new PageResult<>(list, page.getTotal());
        pageResult.setList(list);
        return pageResult;
    }

    @Transactional(rollbackFor = Exception.class)
    public void sendCustomerCoupon(CouponCustomerPCForm form) {
        Long loginUserId = WebFrameworkUtils.getLoginUserId();
        try (DistributeLock lock = DistributeLock.getLock(DEDUCE_COUPONS_LOCK + ":" + loginUserId)) {
            if (lock.tryLock()) {
                CouponEntity coupon = couponMapper.selectById(form.getCouponId());
                if (coupon == null) {
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "此优惠券不存在");
                }
                //如果券类型是预定优惠，老带新，或者新签约报错，不可用手动发这些类型的券
                if (coupon.getCouponType().intValue() == CouponTypeEnum.RESERVATION_DISCOUNT.getNum().intValue()
                        || coupon.getCouponType().intValue() == CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum().intValue()
                        || coupon.getCouponType().intValue() == CouponTypeEnum.NEW_SIGNING_DISCOUNT.getNum().intValue()) {
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "不可用手动发此券");
                }
                if (CouponStatusEnum.IN_PROGRESS.getCode().equals(coupon.getCouponStatus())) {
                    //先考虑库存够不够
                    if (coupon.getSurplusStock().intValue() != -1 && coupon.getSurplusStock().intValue() < form.getCouponNum()) {
                        throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "此券库存不够发");
                    }
                    //库存够的情况下，先新增发放记录，再发放个人券
                    CouponRecordEntity couponRecordEntity = memberCouponRecordRespository.sendManualCouponRecord(coupon, form);
                    //发券给个人
                    //根据客户手机号查询客户信息
                    MemberUser user = userService.getUserByMobile(form.getUserPhone());
                    //如果发券账户不存在
                    if (user == null) {
                        throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "发券账户不存在");
                    }
                    memberCouponCustomerRepository.sendManualCouponCoupon(coupon, user, couponRecordEntity);
                    //扣减库存
                    if (coupon.getStock().intValue() != -1) {
                        memberCouponRepository.deduceStock(coupon.getId(), form.getCouponNum());
                    } else {
                        memberCouponRepository.addSendStock(coupon.getId(), form.getCouponNum());
                    }

                } else {
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "优惠活动状态异常");
                }
            }
        }
    }

    public CouponEntity getCouponById(String couponId) {
        return couponMapper.selectById(couponId);
    }

    public void updateById(CouponEntity coupon) {
        couponMapper.updateById(coupon);
    }

    public List<CouponEntity> getAvailableCouponsByStoreId(Long storeId, Integer couponType) {
        return couponMapper.selectAvailableCouponsByStoreId(storeId, couponType);
    }

    private String createProcessInstance(CouponEntity entity) {
        BpmProcessInstanceCreateReqDTO dto = new BpmProcessInstanceCreateReqDTO();
        dto.setProcessDefinitionKey(processDefinitionKey);//couponFlow
        dto.setTenantId(SecurityFrameworkUtils.getLoginUser().getTenantId());
        dto.setBusinessKey(entity.getId().toString());//主键
        dto.setBusinessType(BpmBusinessTypeEnum.COUPON.name());
        dto.setServiceName(applicationName);//应用名
        CommonResult<String> instanceId = bpmProcessInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(), dto);
        return instanceId.getCheckedData();
    }

    /**
     * 导出优惠券列表
     *
     * @param form
     * @return
     */
    public List<CouponListExportVO> exportCouponList(CouponQueryForm form) {
        List<CouponListExeclVO> list = memberCouponRepository.exportCouponList(form);
        for (CouponListExeclVO c : list) {
            //优惠券类型
            c.setCouponTypeName(CouponTypeEnum.getDesc(c.getCouponType()));
            //优惠内容
            c.setOfferContent(getOfferContent(c));
            //活动期限
            String activityDuration = DateUtil.formatDateTime(c.getActivityStartTime()) + "至" + DateUtil.formatDateTime(c.getActivityEndTime());
            c.setActivityDuration(activityDuration);
            //门店信息
            List<CouponApartmentVO> apartmentIds = c.getApartmentIds();
            StringBuffer sb = new StringBuffer();
            if (apartmentIds != null && apartmentIds.size() > 0) {
                for (int i = 0; i < apartmentIds.size(); i++) {
                    Long apartmentId = apartmentIds.get(i).getApartmentId();
                    String name = "";
                    if (apartmentId.intValue() != -1) {
                        try {
                            CommonResult<ApartmentListDto> result = apartmentApi.getById(apartmentId);
                            if (result.isSuccess()) {
                                if (ObjectUtils.isNotEmpty(result.getData()) && StringUtils.isNotEmpty(result.getData().getName())) {
                                    name = result.getData().getName();
                                }
                            }
                        } catch (Exception e) {
                            logger.error("获取门店失败", e);
                        }
                    } else {
                        name = "不限门店";
                    }
                    if (i < (apartmentIds.size() - 1)) {
                        sb.append(name).append(",");
                    } else {
                        sb.append(name);
                    }
                }
            }
            c.setApartmentName(sb.toString());
            //状态
            c.setCouponStatusName(CouponStatusEnum.getDescByCode(c.getCouponStatus()));
            //总量
            if (c.getStock().intValue() == -1) {
                c.setStockNum("无限制");
            } else {
                c.setStockNum(c.getStock().toString());
            }

            //剩余量量
            if (c.getSurplusStock().intValue() == -1) {
                c.setSurplusStockNum("无限制");
            } else {
                c.setSurplusStockNum(c.getSurplusStock().toString());
            }
        }
        List<CouponListExportVO> couponListExportVOS = list.stream().map(c -> {
            CouponListExportVO vo = new CouponListExportVO();
            BeanUtils.copyProperties(c, vo);
            return vo;
        }).collect(Collectors.toList());
        return couponListExportVOS;
    }

    //优惠券内容
    private String getOfferContent(CouponListExeclVO c) {
        List<String> list = new ArrayList<>();
        //老带新
        if (c.getCouponType().intValue() == CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum().intValue()) {
            if (c.getPreferentialContentType().intValue() == 0) {
                list.add("新客立减" + c.getMarginPreference() + "元");
            } else {
                list.add("新客打" + c.getMarginPreference() + "折");
            }

            if (c.getPreferentialContentTypeOld().intValue() == 0) {
                list.add("老客立减" + c.getMarginPreferenceOld() + "元");
            } else {
                list.add("老客打" + c.getMarginPreferenceOld() + "折");
            }
        } else {
            String prefix = "";
            if (c.getCouponType().intValue() == CouponTypeEnum.NEW_SIGNING_DISCOUNT.getValue().intValue()) {
                prefix = "每期账单";
            }
            if (c.getPreferentialContentType() == 0) {
                list.add(prefix + "立减" + c.getMarginPreference() + "元");
            } else {
                list.add(prefix + "打" + c.getMarginPreference() + "折");
            }
        }
        return String.join(";", list);
    }
}

